package com.fqgj.xjd.user.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fqgj.common.api.Response;
import com.fqgj.common.utils.CollectionUtils;
import com.fqgj.common.utils.MD5;
import com.fqgj.exception.common.ApiErrorException;
import com.fqgj.exception.enums.BasicErrorCodeEnum;
import com.fqgj.xjd.user.client.UserKycDocumentService;
import com.fqgj.xjd.user.client.enums.UserKycStatusEnum;
import com.fqgj.xjd.user.client.enums.UserKycTypeEnum;
import com.fqgj.xjd.user.client.request.KycQueryRequest;
import com.fqgj.xjd.user.client.request.UserKycPageQueryRO;
import com.fqgj.xjd.user.client.request.UserKycUpdateRequest;
import com.fqgj.xjd.user.client.response.*;
import com.fqgj.xjd.user.common.enums.UserErrorCodeEnum;
import com.fqgj.xjd.user.dao.*;
import com.fqgj.xjd.user.entity.*;
import com.fqgj.xjd.user.entity.business.UserCarrierStatisticsEntity;
import com.fqgj.xjd.user.entity.business.UserKycStatisticsEntity;
import com.fqgj.xjd.user.entity.business.UserPanStatisticsEntity;
import com.fqgj.xjd.user.integration.UserOcrService;
import com.google.common.base.CharMatcher;
import com.google.common.base.Joiner;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.qianli.user.domain.enums.UserAuthStatusEnum;
import com.qianli.user.exception.UserException;
import com.qianli.user.ro.UserStateCode;
import com.qianli.user.service.UserAuthService;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author: moss
 * 2018/10/24
 */
@Service("userKycDocumentService")
public class UserKycDocumentServiceImpl implements UserKycDocumentService {

    public static final Logger LOGGER = LoggerFactory.getLogger(UserKycDocumentServiceImpl.class);
    @Autowired
    UserKycDocumentDao userKycDocumentDao;
    @Autowired
    UserKycAadhaarInfoDao userKycAadhaarInfoDao;
    @Autowired
    UserAuthService userAuthService;
    @Autowired
    UserDao userDao;
    @Autowired
    UserAccessDao userAccessDao;
    @Autowired
    UserBaseDao userBaseDao;
    @Autowired
    UserOcrPassportFrontDao userOcrPassportFrontDao;
    @Autowired
    UserOcrPassportBackDao userOcrPassportBackDao;
    @Autowired
    UserOcrService userOcrService;
    @Autowired
    UserOcrVoteridFrontDao userOcrVoteridFrontDao;
    @Autowired
    UserOcrVoteridBackDao userOcrVoteridBackDao;
    @Autowired
    TTaskCenterDao taskCenterDao;
    @Autowired
    UserKycVoterAuthResultDao userKycVoterAuthResultDao;
    @Autowired
    UserKycDriverLicenseResultDao userKycDriverLicenseResultDao;
    @Autowired
    UserAuthPanDao userAuthPanDao;
    @Autowired
    UserContactCarrierDao userContactCarrierDao;

    /**
     * 获取用户kyc信息
     */
    @Override
    public Response<List<UserKycDocumentInfo>> getByUserCode(String userCode) {
        if (StringUtils.isEmpty(userCode)) {
            throw new ApiErrorException("userCode is empty");
        }
        Map<String, Object> map = new HashMap<>(1);
        map.put("userCode", userCode);
        List<UserKycDocumentEntity> userKycDocumentEntities = userKycDocumentDao.selectByParams(map);
        if (userKycDocumentEntities == null || userKycDocumentEntities.isEmpty()) {
            return Response.ok().putData(null);
        }
        return Response.ok().putData(geUserKycDocumentInfoList(userKycDocumentEntities));
    }

    @Override
    public Response<List<UserKycDocumentInfo>> getListByPage(UserKycPageQueryRO userKycPageQueryRO) {
        if(userKycPageQueryRO == null || userKycPageQueryRO.getEndDate() == null){
            return Response.error(BasicErrorCodeEnum.PARAM_NOT_COMPLETE, "param can not be empty");
        }
        List<UserKycDocumentEntity> userKycDocumentEntities = userKycDocumentDao.selectListByPage(userKycPageQueryRO.getPage(), userKycPageQueryRO.getEndDate());
        List<UserKycDocumentInfo> userKycDocumentInfoList = Lists.newArrayList();
        if(CollectionUtils.isNotEmpty(userKycDocumentEntities)){
            for(UserKycDocumentEntity entity : userKycDocumentEntities){
                UserKycDocumentInfo userKycDocumentInfo = new UserKycDocumentInfo();
                BeanUtils.copyProperties(entity, userKycDocumentInfo);
                userKycDocumentInfoList.add(userKycDocumentInfo);
            }
        }
        return Response.ok().putData(userKycDocumentInfoList);
    }

    /**
     * 保存/更新用户kyc信息
     */
    @Override
    public Response saveUserKycInfo(UserKycDocumentInfo userKycDocumentInfo) {
        if (userKycDocumentInfo == null || StringUtils.isEmpty(userKycDocumentInfo.getUserCode())) {
            throw new ApiErrorException("userCode is empty");
        }
        if (userKycDocumentInfo.getAuthType() == null) {
            throw new ApiErrorException("authType is empty");
        }

        Map<String, Object> map = new HashMap<>();
        String userCode = userKycDocumentInfo.getUserCode();
        String authType = userKycDocumentInfo.getAuthType().getType();
        map.put("userCode", userCode);
        map.put("authType", authType);
        List<UserKycDocumentEntity> userKycDocumentEntities = userKycDocumentDao.selectByParams(map);
        LOGGER.info("saveUserKycInfo,userKycDocumentEntities:{},userCode:{}", userKycDocumentEntities != null ? JSONObject.toJSONString(userKycDocumentEntities) : null, userCode);
        if (userKycDocumentEntities == null || userKycDocumentEntities.isEmpty()) {
            //新增
            UserKycDocumentEntity userKycDocumentEntity = new UserKycDocumentEntity();
            BeanUtils.copyProperties(userKycDocumentInfo, userKycDocumentEntity);
            userKycDocumentEntity.setAuthType(userKycDocumentInfo.getAuthType().getType());
            userKycDocumentEntity.setAuthName(userKycDocumentInfo.getAuthType().name());
            userKycDocumentEntity.setAuthDocumentId(0);
            userKycDocumentEntity.setHumanBodyNum(0);
            checkStatus(userKycDocumentEntity);
            userKycDocumentEntity = userKycDocumentDao.insert(userKycDocumentEntity);

            if (UserKycTypeEnum.AADHAAR.getType().equals(userKycDocumentEntity.getAuthType()) && userKycDocumentInfo.getUserKycAadhaarInfo() != null) {
                try {
                    UserKycAadhaarInfoEntity userKycAadhaarInfoEntity = new UserKycAadhaarInfoEntity();
                    BeanUtils.copyProperties(userKycDocumentInfo.getUserKycAadhaarInfo(), userKycAadhaarInfoEntity);
                    userKycAadhaarInfoEntity.setKycId(userKycDocumentEntity.getId());
                    userKycAadhaarInfoDao.insert(userKycAadhaarInfoEntity);
                } catch (Exception e) {
                    LOGGER.error("userKycAadhaarInfo入库失败,userKycDocumentInfo:{}", JSON.toJSONString(userKycDocumentInfo));
                }
            }

            //实名认证
            UserEntity userEntity = userDao.selectByCustomerCode(userCode);
            UserAccessEntity userAccessEntity = userAccessDao.selectUserAccessByUserCode(userCode);
            UserBaseEntity userBaseEntity = userBaseDao.selectByUserCode(userCode);
            if (userEntity == null && userAccessEntity != null) {
                UserEntity newCustomerEntity = new UserEntity();
                newCustomerEntity.setAppCode(userAccessEntity.getAppCode());
                newCustomerEntity.setCustomerCode(userCode);
                newCustomerEntity.setUserCode(userCode);
                String name = Joiner.on(" ").skipNulls().join(userBaseEntity.getFirstName(), userBaseEntity.getMiddleName(), userBaseEntity.getLastName());
                newCustomerEntity.setName(CharMatcher.WHITESPACE.trimAndCollapseFrom(name, ' '));
                newCustomerEntity.setIdentityNo(userKycDocumentInfo.getCardId());
                newCustomerEntity.setMobile(userAccessEntity.getMobile());
                newCustomerEntity.setMd5Mobile(MD5.md5(userAccessEntity.getMobile()));
                newCustomerEntity.setMd5MobileIdentityNo(MD5.md5(userAccessEntity.getMobile() + userKycDocumentInfo.getCardId()));
                userDao.insert(newCustomerEntity);
                userAccessDao.updateCustomerCodeByUserCode(userCode, userCode);
            }
            if (UserKycTypeEnum.VOTER_ID.getType().equals(authType) || UserKycTypeEnum.DRIVER_LICENSE.getType().equals(authType)) {
                // 保存任务
                //taskCenterDao.addTask(userCode, userKycDocumentInfo.getCardId(), TaskTypeEnum.getType(authType).getType());
            }
        } else {
            //更新
            UserKycDocumentEntity userKycDocumentEntity = userKycDocumentEntities.get(0);
            if (StringUtils.isNotBlank(userKycDocumentInfo.getCardId())) {
                userKycDocumentEntity.setCardId(userKycDocumentInfo.getCardId());
            }
            if (StringUtils.isNotBlank(userKycDocumentInfo.getCardFrontUrl())) {
                userKycDocumentEntity.setCardFrontUrl(userKycDocumentInfo.getCardFrontUrl());
            }
            if (StringUtils.isNotBlank(userKycDocumentInfo.getCardBackUrl())) {
                userKycDocumentEntity.setCardBackUrl(userKycDocumentInfo.getCardBackUrl());
            }
            if (StringUtils.isNotBlank(userKycDocumentInfo.getHandHoldUrl())) {
                userKycDocumentEntity.setHandHoldUrl(userKycDocumentInfo.getHandHoldUrl());
            }
            if (StringUtils.isNotBlank(userKycDocumentInfo.getSelfieUrl())) {
                userKycDocumentEntity.setSelfieUrl(userKycDocumentInfo.getSelfieUrl());
            }
            if (Objects.nonNull(userKycDocumentInfo.getHumanBodyNum())) {
                userKycDocumentEntity.setHumanBodyNum(userKycDocumentInfo.getHumanBodyNum());
            }
            if (userKycDocumentInfo.getStatus() != null && userKycDocumentInfo.getStatus().equals(UserKycStatusEnum.RE_UPLOAD)) {
                userKycDocumentEntity.setStatus(UserKycStatusEnum.RE_UPLOAD.getStatus());
            } else {
                checkStatus(userKycDocumentEntity);
            }

            userKycDocumentDao.updateByPrimaryKey(userKycDocumentEntity);

            if (UserKycTypeEnum.AADHAAR.getType().equals(userKycDocumentEntity.getAuthType()) && userKycDocumentInfo.getUserKycAadhaarInfo() != null) {
                try {
                    UserKycAadhaarInfoEntity userKycAadhaarInfoEntity = new UserKycAadhaarInfoEntity();
                    BeanUtils.copyProperties(userKycDocumentInfo.getUserKycAadhaarInfo(), userKycAadhaarInfoEntity);
                    userKycAadhaarInfoEntity.setKycId(userKycDocumentEntity.getId());
                    userKycAadhaarInfoDao.insert(userKycAadhaarInfoEntity);
                } catch (Exception e) {
                    LOGGER.error("userKycAadhaarInfo入库失败,userKycDocumentInfo:{}", JSON.toJSONString(userKycDocumentInfo));
                }
            }
        }
        return Response.ok();
    }

    @Override
    public Response initUserKycInfo(UserKycDocumentInfo userKycDocumentInfo) {
        if (userKycDocumentInfo == null || StringUtils.isEmpty(userKycDocumentInfo.getUserCode())) {
            throw new ApiErrorException("userCode is empty");
        }
        if (userKycDocumentInfo.getAuthType() == null) {
            throw new ApiErrorException("authType is empty");
        }

        Map<String, Object> map = new HashMap<>();
        String userCode = userKycDocumentInfo.getUserCode();
        String authType = userKycDocumentInfo.getAuthType().getType();
        map.put("userCode", userCode);
        map.put("authType", authType);
        List<UserKycDocumentEntity> userKycDocumentEntities = userKycDocumentDao.selectByParams(map);
        LOGGER.info("saveUserKycInfo,userKycDocumentEntities:{},userCode:{}", userKycDocumentEntities != null ? JSONObject.toJSONString(userKycDocumentEntities) : null, userCode);
        if (userKycDocumentEntities == null || userKycDocumentEntities.isEmpty()) {
            //新增
            UserKycDocumentEntity userKycDocumentEntity = new UserKycDocumentEntity();
            BeanUtils.copyProperties(userKycDocumentInfo, userKycDocumentEntity);
            userKycDocumentEntity.setAuthType(userKycDocumentInfo.getAuthType().getType());
            userKycDocumentEntity.setAuthName(userKycDocumentInfo.getAuthType().name());
            userKycDocumentEntity.setAuthDocumentId(0);
            userKycDocumentEntity.setHumanBodyNum(0);
            checkStatus(userKycDocumentEntity);
            userKycDocumentDao.insert(userKycDocumentEntity);
        } else {
            //更新
            UserKycDocumentEntity userKycDocumentEntity = userKycDocumentEntities.get(0);
            if (StringUtils.isNotBlank(userKycDocumentInfo.getCardId())) {
                userKycDocumentEntity.setCardId(userKycDocumentInfo.getCardId());
            }
            if (StringUtils.isNotBlank(userKycDocumentInfo.getCardFrontUrl())) {
                userKycDocumentEntity.setCardFrontUrl(userKycDocumentInfo.getCardFrontUrl());
            }
            if (StringUtils.isNotBlank(userKycDocumentInfo.getCardBackUrl())) {
                userKycDocumentEntity.setCardBackUrl(userKycDocumentInfo.getCardBackUrl());
            }
            if (StringUtils.isNotBlank(userKycDocumentInfo.getHandHoldUrl())) {
                userKycDocumentEntity.setHandHoldUrl(userKycDocumentInfo.getHandHoldUrl());
            }
            if (StringUtils.isNotBlank(userKycDocumentInfo.getSelfieUrl())) {
                userKycDocumentEntity.setSelfieUrl(userKycDocumentInfo.getSelfieUrl());
            }
            if (Objects.nonNull(userKycDocumentInfo.getHumanBodyNum())) {
                userKycDocumentEntity.setHumanBodyNum(userKycDocumentInfo.getHumanBodyNum());
            }
            if (userKycDocumentInfo.getStatus() != null) {
                userKycDocumentEntity.setStatus(userKycDocumentInfo.getStatus().getStatus());
            }
            userKycDocumentDao.updateByPrimaryKey(userKycDocumentEntity);
        }
        return Response.ok();
    }

    /**
     * 校验状态
     */
    private void checkStatus(UserKycDocumentEntity userKycDocumentEntity) {
        //如果当前状态为重传
        if (userKycDocumentEntity.getStatus() != null && userKycDocumentEntity.getStatus().equals(UserKycStatusEnum.RE_UPLOAD.getStatus())) {
            //且信息已经全部重传则更新状态
            boolean allInfoReUploadSuccess = StringUtils.isNotBlank(userKycDocumentEntity.getCardFrontUrl())
                    && StringUtils.isNotBlank(userKycDocumentEntity.getCardBackUrl())
                    && StringUtils.isNotBlank(userKycDocumentEntity.getHandHoldUrl());
            //&& StringUtils.isNotBlank(userKycDocumentEntity.getSelfieUrl());
            if (allInfoReUploadSuccess) {
                userKycDocumentEntity.setStatus(UserKycStatusEnum.CHECK_SUCCESS.getStatus());
            }
        } else {
            //是否完成所有信息
            boolean isAllComplete = StringUtils.isNotBlank(userKycDocumentEntity.getCardId())
                    && StringUtils.isNotBlank(userKycDocumentEntity.getHandHoldUrl())
                    //&& StringUtils.isNotBlank(userKycDocumentEntity.getSelfieUrl())
                    && StringUtils.isNotBlank(userKycDocumentEntity.getCardFrontUrl())
                    && StringUtils.isNotBlank(userKycDocumentEntity.getCardBackUrl());
            if (isAllComplete) {
                userKycDocumentEntity.setStatus(UserKycStatusEnum.CHECK_SUCCESS.getStatus());
            } else {
                userKycDocumentEntity.setStatus(UserKycStatusEnum.INIT.getStatus());
            }
        }
    }

    /**
     * 重传信息
     *
     * @param userKycDocumentInfo
     * @return
     */
    @Override
    public Response removeUserKycInfo(UserKycDocumentInfo userKycDocumentInfo) {
        //logger.info("==removeUserKycInfo==,request:{}", JSON.toJSON(userKycDocumentInfo));
        String userCode = userKycDocumentInfo.getUserCode();
        Map<String, Object> map = new HashMap<>();
        map.put("userCode", userCode);
        map.put("authType", userKycDocumentInfo.getAuthType().getType());
        List<UserKycDocumentEntity> userKycDocumentEntities = userKycDocumentDao.selectByParams(map);
        if (userKycDocumentEntities == null || userKycDocumentEntities.isEmpty()) {
            throw new ApiErrorException("userKycDocumentEntities is empty");
        }
        UserKycDocumentEntity userKycDocumentEntity = userKycDocumentEntities.get(0);
        if (StringUtils.isNotBlank(userKycDocumentInfo.getCardId())) {
            userKycDocumentEntity.setCardId("");
        }
        if (StringUtils.isNotBlank(userKycDocumentInfo.getCardFrontUrl())) {
            userKycDocumentEntity.setCardFrontUrl("");
        }
        if (StringUtils.isNotBlank(userKycDocumentInfo.getCardBackUrl())) {
            userKycDocumentEntity.setCardBackUrl("");
        }
        if (StringUtils.isNotBlank(userKycDocumentInfo.getHandHoldUrl())) {
            userKycDocumentEntity.setHandHoldUrl("");
        }
        if (StringUtils.isNotBlank(userKycDocumentInfo.getSelfieUrl())) {
            userKycDocumentEntity.setSelfieUrl("");
        }
        if (Objects.nonNull(userKycDocumentInfo.getHumanBodyNum())) {
            userKycDocumentEntity.setHumanBodyNum(userKycDocumentInfo.getHumanBodyNum());
        }
        userKycDocumentEntity.setStatus(UserKycStatusEnum.RE_UPLOAD.getStatus());
        userKycDocumentDao.updateByPrimaryKey(userKycDocumentEntity);
        return null;
    }

    /**
     * 通过ocr扫描获取passport正面信息
     */
    @Override
    public Response<OcrPassportFront> getPassportFrontOcrByUserCode(String userCode) {
        if (StringUtils.isEmpty(userCode)) {
            throw new UserException(UserStateCode.PARAMETER_LACK);
        }
        Map<String, Object> map = new HashMap<>(1);
        map.put("userCode", userCode);
        map.put("deleted", "0");
        List<UserOcrPassportFrontEntity> userOcrPassportFrontEntities = userOcrPassportFrontDao.selectByParams(map);
        OcrPassportFront ocrPassportFront = new OcrPassportFront();
        //没有保存过ocr信息
        if (null == userOcrPassportFrontEntities || userOcrPassportFrontEntities.isEmpty() || !userOcrPassportFrontEntities.get(0).getStatus().equals(UserAuthStatusEnum.AUTHORIZED.getStatus())) {
            //请求ocr接口获取数据
            Response<List<UserKycDocumentInfo>> kycInfoResponse = this.getByUserCode(userCode);
            if (!kycInfoResponse.isSuccess() || kycInfoResponse.getData() == null || CollectionUtils.isEmpty(kycInfoResponse.getData())) {
                //logger.info("====== getPassportFrontOcrByUserCode, getUserKycDocumentInfo not exist, userCode:{} ======", userCode);
                return Response.error("user kyc info, not exist");
            }
            String cardFrontUrl = kycInfoResponse.getData().get(0).getCardFrontUrl();
            if (StringUtils.isEmpty(cardFrontUrl)) {
                //logger.info("====== getPassportFrontOcrByUserCode, getCardFrontUrl not exist, userCode:{} ======", userCode);
                return Response.error("user kyc info, card front url not exist");
            }

            ocrPassportFront = userOcrService.ocrForPassportFront(cardFrontUrl);
            //logger.info("====== ocr for passport front:{} ======", JSON.toJSONString(ocrPassportFront));
            if (ocrPassportFront == null) {
                return Response.error("ocr for passport front is null");
            }
            //存储ocr信息
            UserOcrPassportFrontEntity userOcrPassportFrontEntity = new UserOcrPassportFrontEntity();
            BeanUtils.copyProperties(ocrPassportFront, userOcrPassportFrontEntity);
            userOcrPassportFrontEntity.setStatus(UserAuthStatusEnum.AUTHORIZED.getStatus());
            userOcrPassportFrontEntity.setCount(1);
            userOcrPassportFrontEntity.setUserCode(userCode);
            userOcrPassportFrontDao.insert(userOcrPassportFrontEntity);
        } else {
            UserOcrPassportFrontEntity userOcrPassportFrontEntity = userOcrPassportFrontEntities.get(0);
            BeanUtils.copyProperties(userOcrPassportFrontEntity, ocrPassportFront);
        }

        return Response.ok(ocrPassportFront);
    }

    /**
     * 通过ocr扫描获取passport背面信息
     */
    @Override
    public Response<OcrPassportBack> getPassportBackOcrByUserCode(String userCode) {
        if (StringUtils.isEmpty(userCode)) {
            throw new UserException(UserStateCode.PARAMETER_LACK);
        }
        Map<String, Object> map = new HashMap<>(1);
        map.put("userCode", userCode);
        map.put("deleted", "0");
        List<UserOcrPassportBackEntity> userOcrPassportBackEntities = userOcrPassportBackDao.selectByParams(map);
        OcrPassportBack ocrPassportBack = new OcrPassportBack();
        //没有保存过ocr信息
        if (null == userOcrPassportBackEntities || userOcrPassportBackEntities.isEmpty() || !userOcrPassportBackEntities.get(0).getStatus().equals(UserAuthStatusEnum.AUTHORIZED.getStatus())) {
            //请求ocr接口获取数据
            Response<List<UserKycDocumentInfo>> kycInfoResponse = this.getByUserCode(userCode);
            if (!kycInfoResponse.isSuccess() || kycInfoResponse.getData() == null || CollectionUtils.isEmpty(kycInfoResponse.getData())) {
                //logger.info("====== getPassportBackOcrByUserCode, getUserKycDocumentInfo not exist, userCode:{} ======", userCode);
                return Response.error("user kyc info, not exist");
            }
            String cardBackUrl = kycInfoResponse.getData().get(0).getCardBackUrl();
            if (StringUtils.isEmpty(cardBackUrl)) {
                //logger.info("====== getPassportBackOcrByUserCode, getCardBackUrl not exist, userCode:{} ======", userCode);
                return Response.error("user kyc info, card back url not exist");
            }

            ocrPassportBack = userOcrService.ocrForPassportBack(cardBackUrl);
            //logger.info("====== ocr for passport:{} ======", JSON.toJSONString(ocrPassportBack));
            if (ocrPassportBack == null) {
                return Response.error("ocr for passport back is null");
            }
            //存储ocr信息
            UserOcrPassportBackEntity userOcrPassportBackEntity = new UserOcrPassportBackEntity();
            BeanUtils.copyProperties(ocrPassportBack, userOcrPassportBackEntity);
            userOcrPassportBackEntity.setAddressSplit(JSONObject.toJSONString(ocrPassportBack.getAddressSplit()));
            userOcrPassportBackEntity.setStatus(UserAuthStatusEnum.AUTHORIZED.getStatus());
            userOcrPassportBackEntity.setCount(1);
            userOcrPassportBackEntity.setUserCode(userCode);
            userOcrPassportBackDao.insert(userOcrPassportBackEntity);
        } else {
            UserOcrPassportBackEntity userOcrPassportBackEntity = userOcrPassportBackEntities.get(0);
            BeanUtils.copyProperties(userOcrPassportBackEntity, ocrPassportBack);
            ocrPassportBack.setAddressSplit(JSON.parseObject(userOcrPassportBackEntity.getAddressSplit(), AddressSplit.class));
        }

        return Response.ok(ocrPassportBack);
    }

    /**
     * 移除ocr扫描passport正面信息
     */
    @Override
    public Response removePassportFrontOcrInfo(String userCode) {
        if (StringUtils.isBlank(userCode)) {
            //logger.error("====== removePassportFrontOcrInfo, parameter lack ======");
            throw new UserException(UserStateCode.PARAMETER_LACK);
        }

        userOcrPassportFrontDao.deleteByUserCode(userCode);
        return Response.ok();
    }

    /**
     * 移除ocr扫描passport背面信息
     */
    @Override
    public Response removePassportBackOcrInfo(String userCode) {
        if (StringUtils.isBlank(userCode)) {
            //logger.error("====== removePassportBackOcrInfo, parameter lack ======");
            throw new UserException(UserStateCode.PARAMETER_LACK);
        }

        userOcrPassportBackDao.deleteByUserCode(userCode);
        return Response.ok();
    }

    /**
     * 通过ocr扫描获取voterid正面信息
     */
    @Override
    public Response<OcrVoteridFront> getVoteridFrontOcrByUserCode(String userCode) {
        if (StringUtils.isEmpty(userCode)) {
            throw new UserException(UserStateCode.PARAMETER_LACK);
        }
        Map<String, Object> map = new HashMap<>(1);
        map.put("userCode", userCode);
        map.put("deleted", "0");
        List<UserOcrVoteridFrontEntity> userOcrVoteridFrontEntities = userOcrVoteridFrontDao.selectByParams(map);
        OcrVoteridFront ocrVoteridFront = new OcrVoteridFront();
        //没有保存过ocr信息
        if (null == userOcrVoteridFrontEntities || userOcrVoteridFrontEntities.isEmpty() || !userOcrVoteridFrontEntities.get(0).getStatus().equals(UserAuthStatusEnum.AUTHORIZED.getStatus())) {
            //请求ocr接口获取数据
            Response<List<UserKycDocumentInfo>> kycInfoResponse = this.getByUserCode(userCode);
            if (!kycInfoResponse.isSuccess() || kycInfoResponse.getData() == null || CollectionUtils.isEmpty(kycInfoResponse.getData())) {
                //logger.info("====== getVoteridFrontOcrByUserCode, getUserKycDocumentInfo not exist, userCode:{} ======", userCode);
                return Response.error("user kyc info, not exist");
            }
            String cardFrontUrl = kycInfoResponse.getData().get(0).getCardFrontUrl();
            if (StringUtils.isEmpty(cardFrontUrl)) {
                //logger.info("====== getVoteridFrontOcrByUserCode, getCardFrontUrl not exist, userCode:{} ======", userCode);
                return Response.error("user kyc info, card front url not exist");
            }

            ocrVoteridFront = userOcrService.ocrForVoteridFront(cardFrontUrl);
            //logger.info("====== ocr for voterid front:{} ======", JSON.toJSONString(ocrVoteridFront));
            if (ocrVoteridFront == null) {
                return Response.error("ocr for voterid front is null");
            }
            //存储ocr信息
            UserOcrVoteridFrontEntity userOcrVoteridFrontEntity = new UserOcrVoteridFrontEntity();
            BeanUtils.copyProperties(ocrVoteridFront, userOcrVoteridFrontEntity);
            userOcrVoteridFrontEntity.setStatus(UserAuthStatusEnum.AUTHORIZED.getStatus());
            userOcrVoteridFrontEntity.setCount(1);
            userOcrVoteridFrontEntity.setUserCode(userCode);
            userOcrVoteridFrontDao.insert(userOcrVoteridFrontEntity);
        } else {
            UserOcrVoteridFrontEntity userOcrVoteridFrontEntity = userOcrVoteridFrontEntities.get(0);
            BeanUtils.copyProperties(userOcrVoteridFrontEntity, ocrVoteridFront);
        }

        return Response.ok(ocrVoteridFront);
    }

    /**
     * 通过ocr扫描获取voterid背面信息
     */
    @Override
    public Response<OcrVoteridBack> getVoteridBackOcrByUserCode(String userCode) {
        if (StringUtils.isEmpty(userCode)) {
            throw new UserException(UserStateCode.PARAMETER_LACK);
        }
        Map<String, Object> map = new HashMap<>(1);
        map.put("userCode", userCode);
        map.put("deleted", "0");
        List<UserOcrVoteridBackEntity> userOcrVoteridBackEntities = userOcrVoteridBackDao.selectByParams(map);
        OcrVoteridBack ocrVoteridBack = new OcrVoteridBack();
        //没有保存过ocr信息
        if (null == userOcrVoteridBackEntities || userOcrVoteridBackEntities.isEmpty() || !userOcrVoteridBackEntities.get(0).getStatus().equals(UserAuthStatusEnum.AUTHORIZED.getStatus())) {
            //请求ocr接口获取数据
            Response<List<UserKycDocumentInfo>> kycInfoResponse = this.getByUserCode(userCode);
            if (!kycInfoResponse.isSuccess() || kycInfoResponse.getData() == null || CollectionUtils.isEmpty(kycInfoResponse.getData())) {
                //logger.info("====== getVoteridBackOcrByUserCode, getUserKycDocumentInfo not exist, userCode:{} ======", userCode);
                return Response.error("user kyc info, not exist");
            }
            String cardBackUrl = kycInfoResponse.getData().get(0).getCardBackUrl();
            if (StringUtils.isEmpty(cardBackUrl)) {
                //logger.info("====== getVoteridBackOcrByUserCode, getCardBackUrl not exist, userCode:{} ======", userCode);
                return Response.error("user kyc info, card back url not exist");
            }

            ocrVoteridBack = userOcrService.ocrForVoteridBack(cardBackUrl);
            //logger.info("====== ocr for voterid back:{} ======", JSON.toJSONString(ocrVoteridBack));
            if (ocrVoteridBack == null) {
                return Response.error("ocr for voterid back is null");
            }

            // 处理address
            String address = Strings.nullToEmpty(ocrVoteridBack.getAddress());
            if (address.contains("DATE:")) {
                address = address.substring(0, address.indexOf("DATE:"));
            }
            ocrVoteridBack.setAddress(address);

            //存储ocr信息
            UserOcrVoteridBackEntity userOcrVoteridBackEntity = new UserOcrVoteridBackEntity();
            BeanUtils.copyProperties(ocrVoteridBack, userOcrVoteridBackEntity);
            userOcrVoteridBackEntity.setStatus(UserAuthStatusEnum.AUTHORIZED.getStatus());
            userOcrVoteridBackEntity.setCount(1);
            userOcrVoteridBackEntity.setUserCode(userCode);
            userOcrVoteridBackDao.insert(userOcrVoteridBackEntity);
        } else {
            UserOcrVoteridBackEntity userOcrVoteridBackEntity = userOcrVoteridBackEntities.get(0);
            BeanUtils.copyProperties(userOcrVoteridBackEntity, ocrVoteridBack);
        }

        return Response.ok(ocrVoteridBack);
    }

    /**
     * 移除ocr扫描voterid正面信息
     */
    @Override
    public Response removeVoteridFrontOcrInfo(String userCode) {
        if (StringUtils.isBlank(userCode)) {
            //logger.error("====== removeVoteridFrontOcrInfo, parameter lack ======");
            throw new UserException(UserStateCode.PARAMETER_LACK);
        }

        userOcrVoteridFrontDao.deleteByUserCode(userCode);
        return Response.ok();
    }

    /**
     * 移除ocr扫描voterid背面信息
     */
    @Override
    public Response removeVoteridBackOcrInfo(String userCode) {
        if (StringUtils.isBlank(userCode)) {
            //logger.error("====== removeVoteridBackOcrInfo, parameter lack ======");
            throw new UserException(UserStateCode.PARAMETER_LACK);
        }

        userOcrVoteridBackDao.deleteByUserCode(userCode);
        return Response.ok();
    }

    /**
     * 获取没有经过人脸识别的用户kyc列表
     */
    @Override
    public Response<List<UserKycDocumentInfo>> getNoFaceRecognitionKycList(Integer limitSearch) {
        if (limitSearch == null) {
            return Response.error(UserErrorCodeEnum.PARAM_ERROR);
        }
        List<UserKycDocumentEntity> userKycDocumentEntities = userKycDocumentDao.selectNoFaceRecognitionKycList(limitSearch);
        if (userKycDocumentEntities == null || userKycDocumentEntities.isEmpty()) {
            return Response.ok().putData(null);
        }
        return Response.ok().putData(geUserKycDocumentInfoList(userKycDocumentEntities));
    }

    /**
     * 获取没有经过识别的家庭照
     */
    @Override
    public Response<List<UserKycDocumentInfo>> selectNoScanSelfieList(Integer limitSearch) {
        if (limitSearch == null) {
            return Response.error(UserErrorCodeEnum.PARAM_ERROR);
        }
        List<UserKycDocumentEntity> userKycDocumentEntities = userKycDocumentDao.selectNoScanSelfieList(limitSearch);
        if (userKycDocumentEntities == null || userKycDocumentEntities.isEmpty()) {
            return Response.ok().putData(null);
        }
        return Response.ok().putData(geUserKycDocumentInfoList(userKycDocumentEntities));
    }

    @Override
    public Response<UserKycVoterAuthResult> getKycVoterAuthResultByUserCode(String userCode) {
        if (StringUtils.isBlank(userCode)) {
            return Response.error(UserErrorCodeEnum.PARAM_ERROR);
        }

        UserKycVoterAuthResultEntity userKycVoterAuthResultEntity = userKycVoterAuthResultDao.selectByUserCode(userCode);
        if (userKycVoterAuthResultEntity != null) {
            UserKycVoterAuthResult userKycVoterAuthResult = new UserKycVoterAuthResult();
            BeanUtils.copyProperties(userKycVoterAuthResultEntity, userKycVoterAuthResult);
            return Response.ok().putData(userKycVoterAuthResult);
        }

        return Response.ok().putData(null);
    }

    @Override
    public Response<UserKycDriverLicenseAuthResult> getKycDriverLicenseResultByUserCode(String userCode) {
        if (StringUtils.isBlank(userCode)) {
            return Response.error(UserErrorCodeEnum.PARAM_ERROR);
        }

        UserKycDriverLicenseResultEntity userKycDriverLicenseResultEntity = userKycDriverLicenseResultDao.selectByUserCode(userCode);
        if (userKycDriverLicenseResultEntity == null) {
            return Response.ok().putData(null);
        }

        UserKycDriverLicenseAuthResult userKycDriverLicenseAuthResult = new UserKycDriverLicenseAuthResult();
        BeanUtils.copyProperties(userKycDriverLicenseResultEntity, userKycDriverLicenseAuthResult);
        return Response.ok(userKycDriverLicenseAuthResult);
    }

    /**
     * 查询三方服务调用次数
     *
     * @param request
     */
    @Override
    public Response<UserKycStatistics> getUserKycStatistics(KycQueryRequest request) {
        Date startDate = null;
        Date endDate = null;
        if (request.getStartDate() != null && request.getEndDate() != null) {
            startDate = request.getStartDate();
            endDate = request.getEndDate();
            if (startDate.getTime() > endDate.getTime()) {
                Date tmp = startDate;
                startDate = endDate;
                endDate = tmp;
            }
        }
        //aadhaar
        List<UserKycStatisticsEntity> userKycStatisticsEntityList1 = userKycDocumentDao.selectUserKycStatistics("1", startDate, endDate);
        //driver license
        List<UserKycStatisticsEntity> userKycStatisticsEntityList3 = userKycDocumentDao.selectUserKycStatistics("3", startDate, endDate);
        //voter ID
        List<UserKycStatisticsEntity> userKycStatisticsEntityList4 = userKycDocumentDao.selectUserKycStatistics("4", startDate, endDate);

        List<UserPanStatisticsEntity> userPanStatisticsEntityList = userAuthPanDao.selectUserPanStatistics(startDate, endDate);

        List<UserCarrierStatisticsEntity> userCarrierStatisticsEntityList = userContactCarrierDao.selectUserCarrierStatistics(startDate, endDate);

        UserKycStatistics userKycStatistics = new UserKycStatistics();
        userKycStatistics.setAdahaarTotalNum(
                userKycStatisticsEntityList1.stream().mapToInt(item -> item.getNum() == null ? 0 : item.getNum()).sum()
        );
        userKycStatistics.setAdahaarDateNum(
                userKycStatisticsEntityList1.stream().map(e -> {
                    UserKycStatistics.Item item = new UserKycStatistics.Item(e.getDate(), e.getNum());
                    return item;
                }).collect(Collectors.toList())
        );

        userKycStatistics.setDriverLicenseTotalNum(
                userKycStatisticsEntityList3.stream().mapToInt(item -> item.getNum() == null ? 0 : item.getNum()).sum()
        );
        userKycStatistics.setDriverLicenseDateNum(
                userKycStatisticsEntityList3.stream().map(e -> {
                    UserKycStatistics.Item item = new UserKycStatistics.Item(e.getDate(), e.getNum());
                    return item;
                }).collect(Collectors.toList())
        );

        userKycStatistics.setVoterIdTotalNum(
                userKycStatisticsEntityList4.stream().mapToInt(item -> item.getNum() == null ? 0 : item.getNum()).sum()
        );
        userKycStatistics.setVoterIdDateNum(
                userKycStatisticsEntityList4.stream().map(e -> {
                    UserKycStatistics.Item item = new UserKycStatistics.Item(e.getDate(), e.getNum());
                    return item;
                }).collect(Collectors.toList())
        );

        userKycStatistics.setPancardTotalNum(
                userPanStatisticsEntityList.stream().mapToInt(item -> item.getNum() == null ? 0 : item.getNum()).sum()
        );
        userKycStatistics.setPancardDateNum(
                userPanStatisticsEntityList.stream().map(e -> {
                    UserKycStatistics.Item item = new UserKycStatistics.Item(e.getDate(), e.getNum());
                    return item;
                }).collect(Collectors.toList())
        );

        userKycStatistics.setCarrierTotalNum(
                userCarrierStatisticsEntityList.stream().mapToInt(item -> item.getNum() == null ? 0 : item.getNum()).sum()
        );
        userKycStatistics.setCarrierDateNum(
                userCarrierStatisticsEntityList.stream().map(e -> {
                    UserKycStatistics.Item item = new UserKycStatistics.Item(e.getDate(), e.getNum());
                    return item;
                }).collect(Collectors.toList())
        );

        return Response.ok(userKycStatistics);
    }

    private List<UserKycDocumentInfo> geUserKycDocumentInfoList(List<UserKycDocumentEntity> userKycDocumentEntities) {
        List<UserKycDocumentInfo> list = new ArrayList<>();
        for (UserKycDocumentEntity userKycDocumentEntity : userKycDocumentEntities) {
            UserKycDocumentInfo userKycDocumentInfo = new UserKycDocumentInfo();
            BeanUtils.copyProperties(userKycDocumentEntity, userKycDocumentInfo);
            userKycDocumentInfo.setStatus(UserKycStatusEnum.getEnumByStatus(userKycDocumentEntity.getStatus()));
            userKycDocumentInfo.setAuthType(UserKycTypeEnum.getEnumByStatus(userKycDocumentEntity.getAuthType()));
            if (Objects.equals(UserKycTypeEnum.AADHAAR.getType(), userKycDocumentEntity.getAuthType())) {
                long kycId = userKycDocumentEntity.getId();
                UserKycAadhaarInfoEntity userKycAadhaarInfoEntity = userKycAadhaarInfoDao.selectByKycId(kycId);
                if (userKycAadhaarInfoEntity != null) {
                    UserKycAadhaarInfo userKycAadhaarInfo = new UserKycAadhaarInfo();
                    BeanUtils.copyProperties(userKycAadhaarInfoEntity, userKycAadhaarInfo);
                    userKycDocumentInfo.setUserKycAadhaarInfo(userKycAadhaarInfo);
                }
            }
            list.add(userKycDocumentInfo);
        }
        return list;
    }

    @Override
    public Response updateUserKycDocumentInfo(UserKycUpdateRequest request) {
        if(request == null || StringUtils.isBlank(request.getUserCode()) || request.getAuthType() == null){
            return Response.error(BasicErrorCodeEnum.PARAM_NOT_COMPLETE, "userCode can not be empty");
        }
        userKycDocumentDao.updateUserKycDocumentEntity(request.getUserCode(),request.getAuthType(),request.getStatus().getStatus(), request.getCardFrontUrl(),request.getCardBackUrl(),request.getHandHoldUrl());
        return Response.ok();
    }
}
